﻿// Auother:  Rufus Linke,
// Additions: Oliver Assad
using System;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace CalendarWindowsApp.Controls
{
    public delegate void IndexChanged(int index);

    public class PanoramaPanel : Panel
    {
        public static readonly DependencyProperty CenteredIndexProperty =
            DependencyProperty.Register("CenteredIndex",
            typeof(int),
            typeof(PanoramaPanel),
            new PropertyMetadata(0, OnCenteredIndexChanged));

        private bool _isLoaded = false;

        public PanoramaPanel()
        {
            this.RenderTransform = new CompositeTransform();

            Loaded += OnLoaded;
            Unloaded += OnUnloaded;
        }

        public event IndexChanged IndexChanged;

        public int CenteredIndex
        {
            get
            {
                return (int)GetValue(CenteredIndexProperty);
            }
            set
            {
                SetValue(CenteredIndexProperty, value);
            }
        }

        public void OnCenteredIndexChanged(int newValue)
        {
            // Raise the event
            this.IndexChanged(newValue);

            // Move to the designated view
            ScrollToIndex(newValue, true);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            double width = this.DesiredSize.Width;
            double height = finalSize.Height;

            double lastPosX = 0.0;
            foreach (UIElement element in Children)
            {
                var elemRect = new Rect(0.0, 0.0, width, height);
                element.Arrange(elemRect);

                var transform = element.RenderTransform as CompositeTransform;
                if (transform == null)
                {
                    transform = new CompositeTransform();
                    element.RenderTransform = transform;
                }
                transform.TranslateX = lastPosX;
                lastPosX += width;
            }

            ScrollToIndex(CenteredIndex, false);

            return new Size(Math.Max(lastPosX, finalSize.Width), height);
        }

        protected override Windows.Foundation.Size MeasureOverride(Windows.Foundation.Size availableSize)
        {
            double itemWidth = availableSize.Width;
            double itemHeight = availableSize.Height;

            Size itemSize = new Size(itemWidth, itemHeight);

            double totalWidth = 0.0;
            foreach (UIElement element in Children)
            {
                element.Measure(itemSize);

                totalWidth += itemWidth;
            }
            return new Size(Math.Max(totalWidth, availableSize.Width), itemHeight);
        }

        private static void OnCenteredIndexChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((PanoramaPanel)sender).OnCenteredIndexChanged((int)args.NewValue);
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            _isLoaded = true;
            ScrollToIndex(CenteredIndex, false);
        }

        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
            _isLoaded = false;
        }

        private void ScrollToIndex(int selectedIndex, bool animate = true)
        {
            if (!_isLoaded)
                return;

            Storyboard sb = new Storyboard();

            int i = 0;
            foreach (UIElement element in Children)
            {
                var transform = element.RenderTransform as CompositeTransform;
                if (transform != null)
                {
                    int targetIndex = i - selectedIndex;
                    double targetPos = targetIndex * this.DesiredSize.Width;

                    var anim = new DoubleAnimation()
                    {
                        To = targetPos,
                        //Duration = TimeSpan.FromSeconds(1.0),
                        EasingFunction = new CubicEase()
                        {
                            EasingMode = EasingMode.EaseOut
                        }
                    };
                    if (!animate)
                        anim.Duration = TimeSpan.Zero;

                    Storyboard.SetTargetProperty(anim, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
                    Storyboard.SetTarget(anim, element);
                    sb.Children.Add(anim);
                }

                i++;
            }

            sb.Begin();
        }
    }
}